Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • What is wrong with my code by using "if" in foreach loop? Why "{ required" shows up?

    Hello. I typed the following

    count
    foreach i of local r(N){

    foreach x of numlist 2000/2009{

    if year_sign<=`x'{
    replace year`x'=1}
    }
    }
    Then, { required shows up.
    I don't know why. Could you help me and show some reference like Stata help file?

    Here is the data

    clear
    input str5(ISO1 ISO2) float year str6 number int base_treaty float(year_sign yearsign2000 yearsign2001 yearsign2002 yearsign2003 yearsign2004 yearsign2005 yearsign2006 yearsign2007 yearsign2008 yearsign2009)
    "AGO" "BDI" 1991 "3" 3 1991 0 0 0 0 0 0 0 0 0 0
    "AGO" "BEN" 1991 "3" 3 1991 0 0 0 0 0 0 0 0 0 0
    "AGO" "BFA" 1991 "3" 3 1991 0 0 0 0 0 0 0 0 0 0
    "AGO" "BWA" 1991 "3" 3 1991 0 0 0 0 0 0 0 0 0 0
    "AGO" "CAF" 1991 "3" 3 1991 0 0 0 0 0 0 0 0 0 0
    "AGO" "CIV" 1991 "3" 3 1991 0 0 0 0 0 0 0 0 0 0
    "AGO" "CMR" 1991 "3" 3 1991 0 0 0 0 0 0 0 0 0 0
    "AGO" "COD" 1991 "3" 3 1991 0 0 0 0 0 0 0 0 0 0
    "AGO" "COG" 1991 "3" 3 1991 0 0 0 0 0 0 0 0 0 0
    "AGO" "COM" 1991 "3" 3 1991 0 0 0 0 0 0 0 0 0 0
    end
    [/CODE]



  • #2
    The error message you are getting arises from where you write -foreach i of local r(N){-. In the -foreach ... of local ... {- construct, what follows local must be the name of a local macro. r(N) is not the name of a local macro. Now you may be thinking of the fact that we often use the configuration `r(N)' to refer to the result returned by some command (-count-, -summarize-, et al.) in r(). But that does not make r(N) a local macro name. Rather r(N) corresponds to the number of observations found by -count- in your code, which, with the example data is 10. So your code is trying to do something like -foreach i of local 10 {-. But local macro 10 is probably undefined (unless something has happened before that code is reached which defines local macro 10). But even if it were defined, it probably isn't what you want. So that is why you are getting that error. And it has nothing to do with using -if-.

    However, even if we somehow patch up that first -foreach- command, the loop itself makes no sense and won't do anything useful. I can't be sure what you actually want it to do. But whatever that is, I'm sure it won't do it. First of all, the entire outer loop with -foreach i- is superfluous: `i' is never used inside the loop, so whatever `i' is actually supposed to iterate over, it's just going to repeat the exact same thing each time. Next, the construction
    Code:
    count
        foreach x of numlist 2000/2009{
            if year_sign<=`x'{
                replace year`x'=1}
            }
    probably does not do what you think it does. When you write -if year_sign <= `x' {- this is an if command. The way if commands work is the expression following -if- is evaluated once. When variable names are mentioned in the expression (year_sign), they are interpreted as referring to the value of that variable in the first observation. So on each iteration of this loop, the value of year_sign in the first observation of the data set is compared to 2000, and then 2001, then 2002, etc. through 2009. If on any of those iterations, the value of year_sign is less than the current value of the iterator, your -replace- command will be executed (or would be if it, too, didn't have problems--see next paragraph.) Note, by the way, that that -replace- command will be executed in every observation of the data set. But this is pointless. The condition year_sign <= `x' will be met at some point in the iterations if and only if year_sign[1] <= 2009. So you may as well eliminate that loop and just reduce the code to:
    Code:
    if year_sign[1] <= 2009 {
        replace ... // FILL IN SOMETHING CORRECT HERE
    }
    Even when all of that is fixed, you next have -replace year`x'=1-. This is legal syntax, but, again, there is no variable year`x' where `x' is in the range from 2000/2009. So again, you will get an error message complaining year2000 (or year2001, etc.) not found.

    If I knew what you are attempting to do in this code, I would suggest corrections. But I cannot guess what your intentions are from what is written. If you post back explaining what it is you want to do, and refer only to variables that actually exist when doing so, I can try to figure out what the appropriate code would be.

    Comment


    • #3
      You don't need to use a top-level loop for iterating through records (rows). Stata assumes this automatically. So, this is all you would need:

      Code:
      foreach x of numlist 2000/2009 {
          if year_sign <= `x' {
              replace yearsign`x' = 1
          }
      }
      Side note, the variable in replace year`x' = 1 was misspecified.

      Comment


      • #4
        Re #3. This is still very odd code. If this code is really what is wanted, there is no reason to even have all those yearsign2000 through year_sign2009 variables, since all of them will be the same. Moreover, since the value of year_sign in the first observation is 1993, all of them will be set to 1 in all observations. There is no point in storing a single constant in every observation of 9 variables. I would be astonished if this is what O.P. intends to do. And if in the full data set the value of year_sign in the first observation is somewhere in the 2000/2009 range, then all of the yearsign`x' variables with `x' < that value will have 1 in every observation and the rest will have all zero values. This is less odd, but still seems unlikely to be what is wanted.

        Perhaps what is wanted is:
        Code:
        forvalues x = 2000/2009 {
            replace yearsign`x' = 1 if year_sign <= `x'
        }
        This will result in each of the variables potentially being variables, not constants, and the different variables at least potentially differing from each other. (In the example data given, though, year_sign is < 2000 in all observations, so all of the variables will still be 1 in all observations of all variables.)

        I recommend you read https://journals.sagepub.com/doi/abs...urnalCode=stja to understand the difference between the -if- command and the -if- qualifier.
        Last edited by Clyde Schechter; 28 Oct 2023, 16:27.

        Comment


        • #5
          Thanks. The data I showed you is from a large data with one million observations. I only include year2000-year2009. It should be year1945-year2021.

          Comment

          Working...
          X